<!DOCTYPE html>
<html lang="cn">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>测试页面</title>
    <link rel="icon" href="./favicon-32x32.png" type="image/png" />
    <script type="text/javascript" src="op-rec.js"></script>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      canvas {
        display: block;
        width: 100%;
        height: 400px;
      }
    </style>
  </head>
  <body>
    <video controls width="50%" autoplay></video>
    <br />
    <button id="move">webgl 10w个点随机运动</button>
    <canvas id="c" height="400"></canvas>
    <script>
      const video = document.querySelector("video");
      const c = document.querySelector("#c");
      const btn = document.querySelector("#move");
      const gl = c.getContext("webgl");
      let isAnimate = false;
      let timer = null;

      const or = new OpRec({
        url: "http://127.0.0.1:8990",
      });
      or.on("startREC", function (stream) {
        video.srcObject = stream;
        console.log("执行", stream);
        throwError();
      });
      or.on("stopREC", function () {
        clearTimeout(timer);
      });
      // 顶点着色器
      const vertexShader = `
      attribute vec4 a_Position;
      void main() {
        gl_Position = a_Position;
        gl_PointSize = 1.5;
      }`;
      // 片元着色器
      const fragmentShader = `
      void main() {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
      }`;

      const n = 100_000;

      let vertices = new Float32Array(
        Array.from({ length: n * 2 }, () => {
          return Math.random() * (Math.random() > 0.5 ? 1 : -1);
        })
      );

      function initGL() {
        const program = createProgram(gl, vertexShader, fragmentShader);
        gl.program = program;
        gl.useProgram(program);
        refresh();
      }

      function refresh(move = true) {
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.drawArrays(gl.POINTS, 0, initVertexBuffers(gl, move));

        if (isAnimate) {
          requestAnimationFrame(refresh);
        }
      }

      function initVertexBuffers(gl, move = true) {
        if (move) {
          for (let i = 0; i < vertices.length; i++) {
            let target = vertices[i] + 0.01 * (Math.random() > 0.5 ? 1 : -1);
            if (target > 1) {
              target -= Math.random();
            } else if (target < -1) {
              target += Math.random();
            }
            vertices[i] = target;
          }
        }
        const vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
        const a_Position = gl.getAttribLocation(gl.program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(a_Position);
        return n;
      }

      function createProgram(gl, vShader, fShader) {
        const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vShader);
        const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fShader);
        const program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);

        gl.linkProgram(program);
        return program;
      }

      function loadShader(gl, type, source) {
        const shader = gl.createShader(type);
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        return shader;
      }

      initGL();
      resize();

      window.addEventListener("resize", resize);
      btn.addEventListener("click", function () {
        isAnimate = !isAnimate;
        if (isAnimate) {
          requestAnimationFrame(refresh);
          this.innerText = "停止";
        } else {
          this.innerText = "继续";
        }
      });

      function throwError() {
        timer = setTimeout(
          throwError.bind(this, timer),
          Math.round(Math.random() * 2000)
        );
        const randomStr = `随机错误：${Array.from(
          {
            length: Math.ceil(Math.random() * 15),
          },
          () => String.fromCodePoint(Math.round(Math.random() * 20901) + 19968)
        ).join("")}。`;
        if (Math.random() > 0.5) {
          throw new Error(`捕获window${randomStr}`);
        }
        or.logger(Math.round(Math.random() * 7), `主动上报${randomStr}`);
      }
      function resize() {
        c.width = document.body.clientWidth;
        refresh(false);
      }
    </script>
  </body>
</html>
